
package org.uca.dss.curso1011.grupo3.gestionreservas;

import au.com.bytecode.opencsv.CSVReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.IllegalArgumentException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.joda.time.LocalTime;

/**
 *  Esta clase implementa la creacion de los diferentes trayectos que van a formar
 *  parte de nuestro sistema.
 *
 * @author Adolfo Barroso, Levi Orta, Juan Manuel Chaves
 */
public class ListadoTrayectos {

    //Atributos de la clase
    private CSVReader reader;
    private List<Trayecto> listaTrayectos;
    ListadoTrenes listadoTrenes;

    /**
     * Constructor de la clase ListadoTrayectos. Prepara lo necesario para tener un
     * nuevo listado de trayectos.
     *
     * @param listadosTrenes: informacion de todos los trenes usados por el sistema.
     */
    public ListadoTrayectos(ListadoTrenes listadosTrenes)
    {
       listaTrayectos = new ArrayList<Trayecto>();
       this.listadoTrenes = listadosTrenes;

    }

    /**
     * Lee los datos almacenados en un fichero CVS sobre los diferentes trayectos
     * que van a formar parte de nuestro sistema. El metodo lanzara una excepcion si
     * el fichero no se encuentra.
     *
     * @param nombreFichero: cadena que contiene el nombre del fichero donde se guardan los datos de los trayectos.
     */
    public void loadCSV(String nombreFichero) throws FileNotFoundException, IOException
    {
        try {
            this.reader = new CSVReader(new FileReader(nombreFichero));
        } catch (FileNotFoundException ex) {
            throw ex;
        }
        
        String [] Linea;
        //Recorre el fichero hasta encontrar una línea en blanco
        while((Linea = reader.readNext()) != null)
        {
          // Comprobamos que la linea no este vacia
          if(!Linea[0].equals(""))
          {
              //Obtengo el tren dado su nombre
              Tren tren = listadoTrenes.getTren(Linea[0].trim());

              //Si el tren existe, se guardan todos los datos del trayecto
              if(tren != null) //Existe el tren
              {
                  String origen = Linea[1].trim();
                  String destino = Linea[2].trim();
                  int nTramos = Integer.parseInt(Linea[3].trim());
                  Map<LocalTime,LocalTime> horasSalidaLlegada = new HashMap<LocalTime,LocalTime>();

                  // tomamos los datos de 2 en 2 (hora de salida, hora de llegada)
                  for(int i = 0; i < (Linea.length - 4); i+=2)
                  {
                      horasSalidaLlegada.put(new LocalTime(Linea[4+i].trim()), new LocalTime(Linea[4+i+1].trim()));
                  }

                  if(!origen.equals(destino))
                  {
                      //Se genera un nuevo trayecto.
                      Trayecto nuevoTrayecto = new Trayecto(tren, origen, destino, nTramos, horasSalidaLlegada);
                      //Se inserta el trayecto a la lista de trayectos.
                      add(nuevoTrayecto);
                  }
                  else
                      throw new IllegalArgumentException("El origen y el destino son iguales");
              }
          }
        }
    }

    /**
     * Añade un nuevo trayecto al listado de trayectos.
     *
     * @param nuevoTrayecto: nuevo trayecto que va a crear.
     */

    public void add(Trayecto nuevoTrayecto)
    {
        listaTrayectos.add(nuevoTrayecto);
    }

    /**
     * Devuelve el numero de trayectos que existen en el listado.
     *
     * @return numero de trayectos cargados por el sistema.
     */

    public int size()
    {
         return listaTrayectos.size();
    }

    /**
     * Devuelve una lista con los trayectos donde su ciudad de origen y su ciudad
     * de destino son las ciudades dadas como parámetros.
     *
     * @param origen: origen del trayecto.
     * @param destino: destino del trayecto.
     * @return lista con los trayectos que coinciden con el origen y el destino.
     */

    public List<Trayecto> get(String origen, String destino)
    {
        if(!origen.equals(destino))
        {
            List<Trayecto> listaParcialTrayectos = new ArrayList<Trayecto>();

            for(int i = 0; i < size(); ++i)
            {
                //Si el origen y el destino coinciden introduzco el trayecto en la lista.
                if(listaTrayectos.get(i).getOrigen().equals(origen) && listaTrayectos.get(i).getDestino().equals(destino))
                   listaParcialTrayectos.add(listaTrayectos.get(i));
            }
            return listaParcialTrayectos;
        }
        else
            throw new IllegalArgumentException("El origen y el destino son iguales");
    }

    /**
     * Devuelve una lista con los trayectos que salen desde la cidad de origen.
     *
     * @param origen: origen del trayecto.
     * @return lista con los trayectos que coinciden con el origen.
     */

    public List<Trayecto> getDesde(String origen)
    {
        List<Trayecto> listaParcialTrayectos = new ArrayList<Trayecto>();

        for(int i = 0; i < size(); ++i)
        {
            //Si el origen coincide introduzco el trayecto en la lista.
            if(listaTrayectos.get(i).getOrigen().equals(origen))
               listaParcialTrayectos.add(listaTrayectos.get(i));
        }
        return listaParcialTrayectos;
    }

    /**
     * Devuelve una lista con los trayectos que van hasta la cidad de destino.
     *
     * @param destino: destino del trayecto.
     * @return lista con los trayectos que coinciden con el destino.
     */

    public List<Trayecto> getHasta(String destino)
    {
        List<Trayecto> listaParcialTrayectos = new ArrayList<Trayecto>();

        for(int i = 0; i < size(); ++i)
        {
            //Si el destino coinciden introduzco el trayecto en la lista.
            if(listaTrayectos.get(i).getDestino().equals(destino))
               listaParcialTrayectos.add(listaTrayectos.get(i));
        }
        return listaParcialTrayectos;
    }
    
    /**
     * Devuelve el trayecto dado su ciudad de origen, su ciudad de destino y la
     * hora de salida de este.
     *
     * @param origen: origen del trayecto.
     * @param destino: destino del trayecto.
     * @param horaSalida: hora de salida del trayecto.
     * @return lista con los trayectos que coinciden con el origen y el destino.
     */

    public Trayecto getTrayecto(String origen, String destino, LocalTime horaSalida)
    {
        Trayecto trayecto = null;

        for(int i = 0; i < this.size(); ++i)
        {
            //Origen y destino coinciden
            if(listaTrayectos.get(i).getOrigen().equals(origen) && listaTrayectos.get(i).getDestino().equals(destino)
                    &&listaTrayectos.get(i).getHorasSalidaLllegada().containsKey(horaSalida))
                        trayecto = listaTrayectos.get(i);

        }

        if(trayecto != null)
            return trayecto;
        else
            throw new IllegalArgumentException("ListadoTrayectos.getTrayecto: trayecto no encontrado");
    }
}
